<script lang="ts" setup>
import { computed, defineAsyncComponent, nextTick, onMounted, onUnmounted, reactive, ref } from "vue";
import ContextMenu from "@imengyu/vue3-context-menu";
import api from "@/api";
import type { MachineDTO, SftpDTO, SftpFile, SseEvent } from "@/types";
import { useRoute } from "vue-router";
import { ElMessage, ElMessageBox, type TableInstance } from "element-plus";
import SftpUpload from "@/views/SftpUpload.vue";
import { Terminal } from "xterm";
import { FitAddon } from "xterm-addon-fit";
import { TrzszAddon } from "@/utils/xterm";
import "xterm/css/xterm.css";

const route = useRoute();

// --- 新增 SftpEditModal 组件 ---
const SftpEditModal = defineAsyncComponent(() => import('@/components/sftp/SftpEditModal.vue'));
const sftpEditModalRef = ref<any>(null);
const sftpEditModalState = reactive({
  visible: false,
  filePath: '',
  connectionId: '',
  initialContent: '',
  lastModified: 0
});
// --- --- --- --- --- --- --- --- --

const tableRef = ref<TableInstance | null>();
const sftpUploadRef = ref<InstanceType<typeof SftpUpload> | null>();

interface State {
  fold: boolean;
  // tableShow: boolean;
  loading: boolean;
  sftpDTO: SftpDTO;
}

const state = reactive<State>({
  fold: false,
  // tableShow: true,
  loading: false,
  sftpDTO: {
    files: [],
    path: ""
  } as SftpDTO
});

const onContextMenu = (e: MouseEvent) => {
  //prevent the browser's default menu
  e.preventDefault();
  //show your menu
  ContextMenu.showContextMenu({
    x: e.x,
    y: e.y,
    items: [
      {
        label: "刷新",
        onClick: () => {
          loadSftp(state.sftpDTO.path);
        }
      },
      {
        label: "上传",
        onClick: () => {
          sftpUploadRef.value?.openDialog(route.query.id as string, state.sftpDTO.path);
        }
      },
      {
        label: "下载",
        onClick: () => {
          const checkDownload = currentRow.value && currentRow.value.type === "文件";
          if (checkDownload) {
            handleDownload();
          } else {
            ElMessage({
              message: "仅支持文件",
              type: "warning"
            });
          }
        }
      },
      {
        label: "删除",
        onClick: () => {
          // 移除了 checkDelete 的检查
          if (currentRow.value) { // 确保有选中的行
            ElMessageBox.confirm(`确定删除 '${currentRow.value.name}' 吗?`, "提示", {
              confirmButtonText: "确认",
              cancelButtonText: "取消",
              type: "warning"
            }).then(() => {
              // 用户确认删除
              api.sftp
                .rm(route.query.id as string, state.sftpDTO.path + "/" + currentRow.value?.name)
                .then((res) => { // res 是 R<?> 类型的响应
                  // 检查后端返回是否成功
                  // 后端 R 对象结构: { code: "Success" | "GeneralError", message: string, ... }
                  // 成功时 code 为 "Success" 字符串
                  if (res.code === 'Success') {
                     ElMessage.success(res.message || "删除成功");
                     loadSftp(state.sftpDTO.path); // 刷新列表
                  } else {
                     ElMessage.error(res.message || "删除失败");
                  }
                })
                .catch((err) => { // 捕获网络错误或 API 抛出的异常
                   console.error("Delete error:", err);
                   ElMessage.error("删除请求失败");
                });
            }).catch(() => {
              // 用户取消删除，或 ElMessageBox.confirm 本身出错 (较少见)
              // 可以选择不执行任何操作，或给出提示
              // ElMessage.info("已取消删除");
            });
          }
        }
      },
      {
        label: "上一级目录",
        onClick: () => {
          cdUp();
        }
      },
      {
        label: "编辑",
        onClick: () => {
          if (currentRow.value && currentRow.value.type === "文件") {
              handleEditFile();
          } else {
              ElMessage({
                  message: "仅支持编辑文件",
                  type: "warning"
              });
          }
        }
      }
    ]
  });
};

const switchFold = () => {
  state.fold = !state.fold;

  fitAddon.fit();
  sendResize();
};

const machine = ref<MachineDTO>();

const loadMachine = () => {
  api.machine.getMachine(route.query.id as string).then((res) => {
    machine.value = res.data;
  });
};

const loadSftp = (path?: string) => {
  state.loading = true;
  api.sftp
    .ls(route.query.id as string, path)
    .then((res) => {
      state.sftpDTO = res.data;
    })
    .finally(() => {
      state.loading = false;
    });
};

// const width = ref(200);

const sidebarStyles = computed(() => ({
  width: (state.fold ? 60 : 200) + "px"
}));

const currentRow = ref<SftpFile | null>(null);

const handleCurrentChange = (row: SftpFile) => {
  currentRow.value = row;
};

const cd = () => {
  if (state.sftpDTO.path === "/") {
    loadSftp(state.sftpDTO.path + currentRow.value?.name);
  } else {
    loadSftp(state.sftpDTO.path + "/" + currentRow.value?.name);
  }
};

const handleDownload = () => {
  if (state.sftpDTO.path === "/") {
    api.sftp.download(route.query.id as string, state.sftpDTO.path + currentRow.value?.name);
  } else {
    api.sftp.download(route.query.id as string, state.sftpDTO.path + "/" + currentRow.value?.name);
  }
};

// 上一级目录
const cdUp = () => {
  if (state.sftpDTO.path === "/") {
    return;
  }
  const path = state.sftpDTO.path.split("/");
  path.pop();
  loadSftp(path.join("/"));
};

const term = new Terminal({
  cursorBlink: true, // 光标闪烁
  cursorStyle: "underline", // 光标闪烁样式
  fontFamily: 'Consolas, Menlo, Monaco, "Courier New", monospace',
  scrollback: 10000
});

const socketUrl = `ws://127.0.0.1:8899/terminal?id=${route.query.id}`;

// 实例化socket
const socket = new WebSocket(socketUrl);

const sendResize = () => {
  socket.send(
    JSON.stringify({
      type: 2,
      params: {
        cols: term.cols,
        rows: term.rows
      }
    })
  );
};

socket.onopen = function (event) {
  sendResize();
};

const fitAddon = new FitAddon();
term.loadAddon(fitAddon);

const init = () => {
  term.open(document.getElementById("term") as any);
  term.focus();
  fitAddon.fit();
  const trzszAddon = new TrzszAddon(socket);
  term.loadAddon(trzszAddon);
};

const loadTitle = () => {
  api.machine.getMachine(route.query.id as string).then((res) => {
    document.title = "Term: " + res.data.name;
  });
};

const sftpContainerRef = ref<HTMLDivElement>();

const observer = new ResizeObserver((entries: any) => {
  for (const entry of entries) {
    const { width, height } = entry.contentRect;
    console.log(`宽度：${width}px，高度：${height}px`);
    // 这里可以执行针对宽高变化的操作
    if (socket.readyState === WebSocket.OPEN) {
      handleDrag();
    }
  }
});

const handleDrag = () => {
  console.log("handleDrag");
  fitAddon.fit();
  sendResize();
  // resizeTable();
};

// Drag and drop handlers
const handleDragOver = (e: DragEvent) => {
  e.preventDefault();
  e.stopPropagation();
  // Optional: Add visual feedback
  if (tableRef.value?.$el) {
    tableRef.value.$el.style.backgroundColor = '#e0f7fa'; // Light blue highlight
  }
};

const handleDrop = (e: DragEvent) => {
  e.preventDefault();
  e.stopPropagation();
  // Remove visual feedback
  if (tableRef.value?.$el) {
    tableRef.value.$el.style.backgroundColor = '';
  }

  const files = e.dataTransfer?.files;
  if (!files || files.length === 0) {
    ElMessage.info('未检测到拖拽的文件');
    console.log('No files dropped.');
    return;
  }

  const droppedFile = files[0];
  console.log('Dropped file:', droppedFile.name);

  // Use the SftpUpload component's dialog and logic
  const machineId = route.query.id as string;
  const uploadPath = state.sftpDTO.path;

  if (!machineId || !uploadPath) {
    ElMessage.error('缺少上传所需信息');
    return;
  }

  // Open the dialog first
  sftpUploadRef.value?.openDialog(machineId, uploadPath);
  // Then trigger the upload with the dropped file
  // We need to wait for the dialog to open and the internal state to be ready
  nextTick(() => {
     sftpUploadRef.value?.uploadFile(droppedFile);
  });
};

const handleUploadSuccess = () => {
  loadSftp(state.sftpDTO.path);
  sftpUploadRef.value?.closeDialog();
};

// --- 新增编辑文件的处理函数 ---
const handleEditFile = async () => {
  if (!currentRow.value) return;

  const filePath = state.sftpDTO.path === '/' ? `/${currentRow.value.name}` : `${state.sftpDTO.path}/${currentRow.value.name}`;
  const connectionId = route.query.id as string;

  try {
    // 1. 调用 API 获取文件内容和元数据
    const res = await api.sftp.fetchFileContent(connectionId, filePath);
    if (res.code === 'Success' && res.data) {
      // 2. 打开编辑弹窗
      sftpEditModalState.filePath = filePath;
      sftpEditModalState.connectionId = connectionId;
      sftpEditModalState.initialContent = res.data.content;
      sftpEditModalState.lastModified = res.data.lastModified;
      sftpEditModalState.visible = true;
    } else {
      ElMessage.error(res.message || '获取文件内容失败');
    }
  } catch (error: any) {
    console.error('获取文件内容时发生错误:', error);
    ElMessage.error(error.message || '获取文件内容失败');
  }
};

const handleEditSuccess = () => {
  // 编辑成功后，刷新 SFTP 文件列表
  loadSftp(state.sftpDTO.path);
  // 可以选择性地给出提示
  // ElMessage.success('文件已保存');
};
// --- --- --- --- --- --- --- --- --- ---

onMounted(() => {
  observer.observe(sftpContainerRef.value as any);
  loadMachine();
  loadSftp();
  init();
  window.addEventListener("resize", () => {
    fitAddon.fit();
    sendResize();
  });
  window.addEventListener("beforeunload", () => {
    socket.close();
  });
  loadTitle();

  // Add event listeners for drag and drop
  nextTick(() => {
    if (tableRef.value?.$el) {
      tableRef.value.$el.addEventListener('dragover', handleDragOver);
      tableRef.value.$el.addEventListener('drop', handleDrop);
    }
  });
});

onUnmounted(() => {
  observer.disconnect();
  // Remove event listeners
   if (tableRef.value?.$el) {
      tableRef.value.$el.removeEventListener('dragover', handleDragOver);
      tableRef.value.$el.removeEventListener('drop', handleDrop);
   }
});
</script>

<template>
  <div h-full w-full flex flex-row>
    <div bg-slate-200 h-full :style="sidebarStyles">
      <div :style="sidebarStyles" flex flex-row p-2 bg-slate-100 h-14>
        <div v-if="!state.fold" flex-1 flex justify-center items-center>主机信息</div>
        <el-button :icon="!state.fold ? 'DArrowLeft' : 'DArrowRight'" @click="switchFold">
        </el-button>
      </div>
      <div :style="sidebarStyles" flex-1 v-if="!state.fold">
        <div>主机名：{{ machine?.name }}</div>
        <div>主机信息：{{ machine?.ip }}</div>
        <div>用户名：{{ machine?.username }}</div>
        <div>SFTP：{{ state.sftpDTO.path }}</div>
      </div>
    </div>
    <div flex-1 h-full bg-slate-400 overflow-x-hidden>
      <div h-full w-full flex flex-col>
        <div w-full h-14 flex-1 id="term"></div>
        <div w-full h-300px bg-slate-200 flex flex-col ref="sftpContainerRef" v-resizable="'top'">
          <el-table
            ref="tableRef"
            v-loading="state.loading"
            :data="state.sftpDTO.files"
            highlight-current-row
            @contextmenu="onContextMenu"
            @row-dblclick="cd"
            @current-change="handleCurrentChange"
            @row-contextmenu="handleCurrentChange"
            flex-1
          >
            <!--    <el-table-column type="selection" width="55" />-->
            <el-table-column prop="name" label="文件名" min-width="280">
              <template #default="scope">
                <span v-if="scope.row.type === '文件夹'">
                  <el-icon><Folder /></el-icon>
                  {{ scope.row.name }}
                </span>
                <span v-else>
                  <el-icon><List /></el-icon>
                  {{ scope.row.name }}
                </span>
              </template>
            </el-table-column>
            <el-table-column prop="size" label="大小" min-width="180" />
            <el-table-column prop="type" label="类型" />
            <el-table-column prop="lastModified" min-width="120" label="修改时间" />
            <el-table-column prop="permission" label="权限" />
            <el-table-column prop="owner" label="用户/用户组" />
          </el-table>
          <sftp-upload ref="sftpUploadRef" @success="handleUploadSuccess" />
          <!-- 新增 SftpEditModal 组件 -->
          <SftpEditModal
              v-if="sftpEditModalState.visible"
              ref="sftpEditModalRef"
              v-model="sftpEditModalState.visible"
              :file-path="sftpEditModalState.filePath"
              :connection-id="sftpEditModalState.connectionId"
              :initial-content="sftpEditModalState.initialContent"
              :last-modified="sftpEditModalState.lastModified"
              @success="handleEditSuccess"
          />
        </div>
      </div>
    </div>
  </div>
</template>
